package com.gitee.apanlh.util.net.ftp;

import com.gitee.apanlh.exp.FtpDeleteException;
import com.gitee.apanlh.exp.FtpDownloadException;
import com.gitee.apanlh.exp.FtpUploadException;
import com.gitee.apanlh.util.base.StringUtils;
import com.gitee.apanlh.util.io.IOUtils;
import com.gitee.apanlh.util.log.Log;
import com.gitee.apanlh.util.unit.BuffSize;
import org.apache.commons.net.ftp.FTPClient;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;
import java.util.List;

/**	
 * 	FTP文件相关操作
 * 
 * 	@author Pan
 */
class FtpFile implements FtpCommandFileExecutor {
	
	/** 目录地址对象 */
	private FtpCommandDirectoryPath directoryPath;
	/** 执行器 */
	private FTPClient executor;
	/** FTP命令 */
	private FtpCommand command;
	
	/**
	 * 	构造函数-默认
	 *
	 * 	@author Pan
	 */
	FtpFile() {
		super();
	}
	
	/**	
	 * 	构造函数-加载目录
	 * 	
	 * 	@author Pan
	 * 	@param 	commandExecutor	命令执行器
	 */
	public FtpFile(FtpCommandExecutor commandExecutor) {
		this.command = commandExecutor.getCommand();
		this.executor = commandExecutor.getExecutor();
		this.directoryPath = commandExecutor.getDirectory().getDirectoryPath();
	}

	@Override
	public boolean upload(String fileName, byte[] bytes) {
		return upload(directoryPath.getCurrentPath(), fileName, IOUtils.toByteInput(bytes));
	}
	
	@Override
	public boolean upload(String targetDir, String fileName, byte[] bytes) {
		return upload(targetDir, fileName, IOUtils.toByteInput(bytes));
	}
	
	@Override
	public boolean upload(String fileName, InputStream is) {
		return upload(directoryPath.getCurrentPath(), fileName, is);
	}
	
	@Override
	public boolean upload(String targetDir, String fileName, InputStream is) {
		boolean storeFile;
		try {
			directoryPath.changeWorkingDirectory(targetDir);
			storeFile = executor.storeFile(fileName, is);
			command.isCompletion(true);
			Log.get().info("FTP上传文件:{}", command.getCommandDetails());
		} catch (Exception e) {
			throw new FtpUploadException(StringUtils.format("FTP上传文件时出错:{}", e.getMessage(), e));
		} finally {
			IOUtils.close(is);
		}
		return storeFile;
	}
	
	@Override
	public byte[] download(String fileName) {
		return download(directoryPath.getCurrentPath(), fileName);
	}
	
	@Override
	public byte[] download(String targetDir, String fileName) {
		try {
			ByteArrayOutputStream os = new ByteArrayOutputStream(BuffSize.SIZE_8K);
			directoryPath.changeWorkingDirectory(targetDir);
			executor.retrieveFile(fileName, os);
			command.isCompletion(true);
			Log.get().info("FTP下载文件:{}", command.getCommandDetails());
			return os.toByteArray();
		} catch (Exception e) {
			throw new FtpDownloadException(StringUtils.format("FTP下载文件时出错:{}", e.getMessage(), e));
		}
	}
	
	@Override
	public boolean delFile(String fileName) {
		return delFile(directoryPath.getCurrentPath(), fileName);
	}
	
	@Override
	public boolean delFile(String targetDir, String fileName) {
		boolean isDelSuc;
		try {
			directoryPath.changeWorkingDirectory(targetDir);
			Integer resultCode = executor.dele(fileName);
			isDelSuc = !FtpStatus.isDelSuc(resultCode);
			if (!isDelSuc) {
				Log.get().error("FTP删除文件:false, {}", resultCode);
			}
		} catch (Exception e) {
			throw new FtpDeleteException(StringUtils.format("FTP删除文件时出错:{}", e.getMessage(), e));
		}
		return isDelSuc;
	}
	
	@Override
	public boolean delFiles(String[] filesName) {
		return delFiles(directoryPath.getCurrentPath(), filesName);
	}
	
	@Override
	public boolean delFiles(String targetDir, String[] filesName) {
		return delFiles(targetDir, Arrays.asList(filesName));
	}
	
	@Override
	public boolean delFiles(String targetDir, List<String> filesName) {
		boolean isAllDel = true;
		try {
			directoryPath.changeWorkingDirectory(targetDir);
			for (int i = 0, len = filesName.size(); i < len; i++) {
				String delFileName = filesName.get(i);
				Integer resultCode = executor.dele(delFileName);
				if (!FtpStatus.isDelSuc(resultCode)) {
					isAllDel = false;
					Log.get().error("FTP删除名:{}文件失败,返回状态码为:{}", delFileName , resultCode);
				}
			}
		} catch (IOException e) {
			throw new FtpDeleteException(StringUtils.format("FTP删除多个文件时出错:{}", e.getMessage(), e));
		}
		return isAllDel;
	}

	@Override
	public void beforeConfigure() {
		//	空实现
	}

	@Override
	public void afterConfigure() {
		//	空实现
	}
}
